package main

import (
	"fmt"
	"strings"
)

/**
16_解释器模式
概念：给定一个语言，定义它的文法表示，并定义一个解释器，这个解释器使用该标识来解释语言中的句子。
*/

type Expression interface {
	Interpret(variables map[string]Expression) int
}

type Integer struct {
	integer int
}

func (i *Integer) Interpret(variables map[string]Expression) int {
	return i.integer
}

type Plus struct {
	leftOperand  Expression
	rightOperand Expression
}

func (p *Plus) Interpret(variables map[string]Expression) int {
	return p.leftOperand.Interpret(variables) + p.rightOperand.Interpret(variables)
}

type Evaluator struct {
	syntaxTree Expression
}

func (e *Evaluator) Interpret(variables map[string]Expression) int {
	return e.syntaxTree.Interpret(variables)
}

type Variable struct {
	name string
}

type Node struct {
	value interface{}
	next  *Node
}

type Stack struct {
	top  *Node
	size int
}

func (s *Stack) Push(value interface{}) {
	s.top = &Node{
		value: value,
		next:  s.top,
	}
	s.size++
}

func (s *Stack) Pop() interface{} {
	if s.size == 0 {
		return nil
	}

	value := s.top.value
	s.top = s.top.next
	s.size--
	return value
}

func (v *Variable) Interpret(variables map[string]Expression) int {
	value, found := variables[v.name]
	if !found {
		return 0
	}
	return value.Interpret(variables)
}

func NewEvaluator(expression string) *Evaluator {
	expressionStack := new(Stack)
	for _, token := range strings.Split(expression, " ") {
		switch token {
		case "+":
			right := expressionStack.Pop().(Expression)
			left := expressionStack.Pop().(Expression)
			subExpression := &Plus{left, right}
			expressionStack.Push(subExpression)
		default:
			expressionStack.Push(&Variable{token})
		}
	}
	syntaxTree := expressionStack.Pop().(Expression)
	return &Evaluator{syntaxTree: syntaxTree}
}

func main() {
	sentence := NewEvaluator("w x z +")
	variable := make(map[string]Expression)
	variable["w"] = &Integer{6}
	variable["x"] = &Integer{10}
	variable["z"] = &Integer{41}
	result := sentence.Interpret(variable)
	if result == 51 {
		fmt.Println("正确")
	} else {
		fmt.Println("错误")
	}
}
